//
//  SDC.cpp
//  
//
//  Created by Kun Zhao on 13/01/25.
//  Copyright (c) 2013 Kyoto University. All rights reserved.
//

#include "SDC.h"
#include "float.h"

namespace kun 
{
    SDC::SDC( void ) {}
    
    SDC::SDC( std::string filename )
    {
        this->read( filename );
    }

    SDC::SDC( size_t block_size, kvs::Vector3ui resolution, kvs::ValueArray<float> values )
    {
        m_block_size = block_size;
        m_resolution = resolution;
        m_values = values;
        this->updateMinMaxValues();
    }
    
    void SDC::setBlockSize( size_t block_size )
    {
        m_block_size = block_size;
    }
    
    void SDC::setResolution( kvs::Vector3ui resolution )
    {
        m_resolution = resolution;
    }
    
    void SDC::setValues( kvs::ValueArray<float> values )
    {
        m_values = values;
    }
    
    size_t SDC::blockSize( void )
    {
        return m_block_size;
    }
    
    kvs::Vector3ui SDC::resolution( void )
    {
        return m_resolution;
    }
    
    kvs::ValueArray<float> SDC::values( void )
    {
        return m_values;
    }
        
    void SDC::updateMinMaxValues( void )
    {
        m_min_value = FLT_MAX;
        m_max_value = -FLT_MAX;
        float* pvalues = m_values.pointer();
        for ( size_t i = 0; i < m_values.size(); i ++)
        {
            if ( pvalues[i] < m_min_value ) m_min_value = pvalues[i];
            if ( pvalues[i] > m_max_value ) m_max_value = pvalues[i];
        }
    }
    
    void SDC::read( std::string filename )
    {
        FILE *rawfile = fopen( filename.c_str(), "rb" );
        fseek( rawfile, 0, SEEK_END );
        size_t end = ftell( rawfile );
        size_t length = end / sizeof(float);
        fseek( rawfile, 0 , SEEK_SET );    
        float buf[4];
        fread( buf, sizeof( float ), 4, rawfile );
        m_values.allocate( length - 4 );
        float* pvalues = m_values.pointer();
        fread( &pvalues[0], sizeof( float ), length - 4, rawfile );
        fclose(rawfile);
        
        m_block_size = (unsigned int)buf[0];
        m_resolution.x() = (unsigned int)buf[1]; 
        m_resolution.y() = (unsigned int)buf[2]; 
        m_resolution.z() = (unsigned int)buf[3];
    }
    
    void SDC::write( std::string filename )
    {
        size_t nnodes = m_values.size();
//        std::cout << nnodes << std::endl;
        unsigned int length = nnodes + 4;
        float* pvalues = m_values.pointer();
        float* buf = new float[length];
        buf[0] = (float)m_block_size;
        buf[1] = (float)m_resolution.x();
        buf[2] = (float)m_resolution.y();
        buf[3] = (float)m_resolution.z();
        for( size_t i = 0; i < nnodes; i++ ) buf[i + 4] = pvalues[i];
        
        FILE* outputFile = fopen( filename.c_str(), "wb" );
        fwrite( buf, sizeof(float), length, outputFile );
        std::cout << "finish writting the sdc file: " << filename << std::endl;
    }
}
